
// this is autogenerated file, do not edit it.
#include "ficus/ficus.h"


#include <stdio.h>

typedef struct _fx_R7File__t {
   fx_cptr_t handle;
} _fx_R7File__t;

typedef struct {
   int_ rc;
   int_ data;
} _fx_E4Exit_data_t;

typedef struct {
   int_ rc;
   fx_str_t data;
} _fx_E4Fail_data_t;

static void _fx_free_R7File__t(struct _fx_R7File__t* dst)
{
   fx_free_cptr(&dst->handle);
}

static void _fx_copy_R7File__t(struct _fx_R7File__t* src, struct _fx_R7File__t* dst)
{
   fx_copy_cptr(src->handle, &dst->handle);
}

static void _fx_make_R7File__t(fx_cptr_t r_handle, struct _fx_R7File__t* fx_result)
{
   fx_copy_cptr(r_handle, &fx_result->handle);
}

int_ _fx_g14File__SEEK_SET = 
(int)SEEK_SET
;
int_ _fx_g14File__SEEK_END = 
(int)SEEK_END
;
_fx_R7File__t _fx_g12File__stdout = {0};
FX_EXTERN_C int _fx_F6assertv1B(bool f_0, void* fx_fv);

FX_EXTERN_C int _fx_M4FileFM13get_stdstreamRM1t1i(int_ i, struct _fx_R7File__t* fx_result, void* fx_fv)
{
   
if(i != 0 && i != 1 && i != 2)
        FX_FAST_THROW_RET(FX_EXN_NullFileError);
    fx_result->handle = fx_get_stdstream(i);
    return FX_OK;

}

FX_EXTERN_C int _fx_M4FileFM5open_p3SSB(fx_str_t* fname, fx_str_t* mode, bool ispipe, fx_cptr_t* fx_result, void* fx_fv)
{
   
fx_cstr_t fname_, mode_;
    int fx_status = fx_str2cstr(fname, &fname_, 0, 0);
    if (fx_status >= 0) {
        fx_status = fx_str2cstr(mode, &mode_, 0, 0);
        if (fx_status >= 0) {
            FILE* f = ispipe ?
            #ifdef _WIN32
                _popen(fname_.data, mode_.data) :
            #else
                popen(fname_.data, mode_.data) :
            #endif
                fopen(fname_.data, mode_.data);
            if (f) {
                fx_status = fx_make_cptr(f, (ispipe ? fx_pipe_destructor :
                                        fx_file_destructor), fx_result);
            }
            else {
                fx_status = FX_SET_EXN_FAST(FX_EXN_FileOpenError);
            }
            fx_free_cstr(&mode_);
        }
        fx_free_cstr(&fname_);
    }
    return fx_status;

}

FX_EXTERN_C int _fx_M4FileFM5popenRM1t2SS(fx_str_t* cmdname_0, fx_str_t* mode_0, struct _fx_R7File__t* fx_result, void* fx_fv)
{
   fx_cptr_t v_0 = 0;
   int fx_status = 0;
   FX_CALL(_fx_M4FileFM5open_p3SSB(cmdname_0, mode_0, true, &v_0, 0), _fx_cleanup);
   _fx_make_R7File__t(v_0, fx_result);

_fx_cleanup: ;
   if (v_0) {
      fx_free_cptr(&v_0);
   }
   return fx_status;
}

FX_EXTERN_C void _fx_M4FileFM5closev1RM1t(struct _fx_R7File__t* f, void* fx_fv)
{
   
if(f->handle && f->handle->ptr) {
        f->handle->free_f(f->handle->ptr);
        f->handle->ptr = 0;
    }

}

FX_EXTERN_C int _fx_M4FileFM18pclose_exit_statusi1RM1t(struct _fx_R7File__t* f, int_* fx_result, void* fx_fv)
{
   
if(!f->handle || !f->handle->ptr || f->handle->free_f != fx_pipe_destructor)
        FX_FAST_THROW_RET(FX_EXN_FileOpenError);

#ifdef _WIN32
    *fx_result = _pclose(f->handle->ptr);
#else
    int result = pclose(f->handle->ptr);
    *fx_result = WEXITSTATUS(result);
#endif

    f->handle->ptr = 0;
    return FX_OK;

}

FX_EXTERN_C int _fx_M4FileFM4seekv3RM1tli(struct _fx_R7File__t* f, int64_t pos, int_ origin, void* fx_fv)
{
   
if(!f->handle || !f->handle->ptr)
        FX_FAST_THROW_RET(FX_EXN_NullFileError);
    int code = fseek((FILE*)(f->handle->ptr), (long)pos, origin);
    return code == 0 ? FX_OK : FX_EXN_IOError;

}

FX_EXTERN_C int _fx_M4FileFM4telll1RM1t(struct _fx_R7File__t* f, int64_t* fx_result, void* fx_fv)
{
   
if(!f->handle || !f->handle->ptr)
        FX_FAST_THROW_RET(FX_EXN_NullFileError);
    long code = ftell((FILE*)(f->handle->ptr));
    if(code == -1) FX_FAST_THROW_RET(FX_EXN_IOError);
    *fx_result = (int64_t)code;
    return FX_OK;

}

FX_EXTERN_C int _fx_M4FileFM5flushv1RM1t(struct _fx_R7File__t* f, void* fx_fv)
{
   
if(!f->handle || !f->handle->ptr)
        FX_FAST_THROW_RET(FX_EXN_NullFileError);
    fflush((FILE*)(f->handle->ptr));
    return FX_OK;

}

FX_EXTERN_C int _fx_M4FileFM5printv2RM1tS(struct _fx_R7File__t* f, fx_str_t* x, void* fx_fv)
{
   
if(!f->handle || !f->handle->ptr)
        FX_FAST_THROW_RET(FX_EXN_NullFileError);
    return fx_fputs((FILE*)(f->handle->ptr), x);

}

FX_EXTERN_C int _fx_M4FileFM4readi2RM1tA1b(struct _fx_R7File__t* f, fx_arr_t* a, int_* fx_result, void* fx_fv)
{
   
if(!f->handle || !f->handle->ptr)
        FX_FAST_THROW_RET(FX_EXN_NullFileError);
    FILE* fh = (FILE*)f->handle->ptr;
    size_t elem_size = a->dim[0].step, count0 = (size_t)a->dim[0].size;
    size_t count = fread(a->data, elem_size, count0, fh);
    *fx_result = (int_)count;
    return count == count0 || feof(fh) ? FX_OK : FX_EXN_IOError;

}

FX_EXTERN_C int _fx_M4FileFM6readlnS1RM1t(struct _fx_R7File__t* f, fx_str_t* fx_result, void* fx_fv)
{
   
if(!f->handle || !f->handle->ptr)
        FX_FAST_THROW_RET(FX_EXN_NullFileError);
    return fx_fgets((FILE*)(f->handle->ptr), fx_result);

}

FX_EXTERN_C int _fx_M4FileFM14read_binary_u8A1b1S(fx_str_t* fname_0, fx_arr_t* fx_result, void* fx_fv)
{
   fx_cptr_t v_0 = 0;
   _fx_R7File__t f_0 = {0};
   fx_arr_t arr_0 = {0};
   int fx_status = 0;
   fx_str_t slit_0 = FX_MAKE_STR("rb");
   FX_CALL(_fx_M4FileFM5open_p3SSB(fname_0, &slit_0, false, &v_0, 0), _fx_cleanup);
   _fx_make_R7File__t(v_0, &f_0);
   FX_CALL(_fx_M4FileFM4seekv3RM1tli(&f_0, 0LL, _fx_g14File__SEEK_END, 0), _fx_cleanup);
   int64_t sz_0;
   FX_CALL(_fx_M4FileFM4telll1RM1t(&f_0, &sz_0, 0), _fx_cleanup);
   FX_CALL(_fx_M4FileFM4seekv3RM1tli(&f_0, 0LL, _fx_g14File__SEEK_SET, 0), _fx_cleanup);
   uint8_t* dstptr_0 = 0;
   int_ v_1 = (int_)sz_0;
   {
      const int_ shape_0[] = { v_1 };
      FX_CALL(fx_make_arr(1, shape_0, sizeof(uint8_t), 0, 0, 0, &arr_0), _fx_cleanup);
   }
   dstptr_0 = (uint8_t*)arr_0.data;
   for (int_ i_0 = 0; i_0 < v_1; i_0++, dstptr_0++) {
      *dstptr_0 = 0u;
   }
   int_ v_2;
   FX_CALL(_fx_M4FileFM4readi2RM1tA1b(&f_0, &arr_0, &v_2, 0), _fx_cleanup);
   FX_CALL(_fx_F6assertv1B(v_2 == (int_)sz_0, 0), _fx_cleanup);
   _fx_M4FileFM5closev1RM1t(&f_0, 0);
   fx_copy_arr(&arr_0, fx_result);

_fx_cleanup: ;
   if (v_0) {
      fx_free_cptr(&v_0);
   }
   _fx_free_R7File__t(&f_0);
   FX_FREE_ARR(&arr_0);
   return fx_status;
}

FX_EXTERN_C int _fx_M4FileFM9read_utf8S1S(fx_str_t* fname, fx_str_t* fx_result, void* fx_fv)
{
   
fx_cstr_t fname_;
    int fx_status = fx_str2cstr(fname, &fname_, 0, 0);
    if (fx_status >= 0) {
        FILE* f = fopen(fname_.data, "rb");
        if (f) {
            fseek(f, 0, SEEK_END);
            int_ size = (int_)ftell(f);
            fseek(f, 0, SEEK_SET);
            fx_cstr_t buf;
            fx_status = fx_make_cstr(0, size, &buf);
            if (fx_status >= 0) {
                int_ count = (int_)fread(buf.data, 1, (size_t)size, f);
                if (count == size) {
                    char* ptr = buf.data;
                    if (count >= 3 && ptr[0] == (char)0xEF && ptr[1] == (char)0xBB && ptr[2] == (char)0xBF) {
                        ptr += 3; count -= 3;
                    }
                    fx_status = fx_cstr2str(ptr, count, fx_result);
                } else {
                    fx_status = FX_SET_EXN_FAST(FX_EXN_IOError);
                }
                fx_free_cstr(&buf);
            }
            fclose(f);
        } else {
            fx_status = FX_SET_EXN_FAST(FX_EXN_FileOpenError);
        }
        fx_free_cstr(&fname_);
    }
    return fx_status;

}

FX_EXTERN_C int _fx_M4FileFM10write_utf8v2SS(fx_str_t* fname, fx_str_t* text, void* fx_fv)
{
   
fx_cstr_t fname_;
    int fx_status = fx_str2cstr(fname, &fname_, 0, 0);
    if (fx_status >= 0) {
        FILE* f = fopen(fname_.data, "wb");
        if (f) {
            fx_cstr_t buf;
            fx_status = fx_str2cstr(text, &buf, 0, 0);
            if (fx_status >= 0) {
                int_ count = (int_)fwrite(buf.data, 1, buf.length, f);
                if (count != buf.length)
                    fx_status = FX_SET_EXN_FAST(FX_EXN_IOError);
                fx_free_cstr(&buf);
            }
            fclose(f);
            if (fx_status < 0)
                remove(fname_.data);
        } else {
            fx_status = FX_SET_EXN_FAST(FX_EXN_FileOpenError);
        }
        fx_free_cstr(&fname_);
    }
    return fx_status;

}

FX_EXTERN_C int fx_init_File(void)
{
   _fx_R7File__t res_0 = {0};
   _fx_R7File__t res_1 = {0};
   int fx_status = 0;
   FX_CALL(_fx_M4FileFM13get_stdstreamRM1t1i(0, &res_0, 0), _fx_cleanup);
   FX_CALL(_fx_M4FileFM13get_stdstreamRM1t1i(1, &_fx_g12File__stdout, 0), _fx_cleanup);
   FX_CALL(_fx_M4FileFM13get_stdstreamRM1t1i(2, &res_1, 0), _fx_cleanup);

_fx_cleanup: ;
   _fx_free_R7File__t(&res_0);
   _fx_free_R7File__t(&res_1);
   return fx_status;
}

FX_EXTERN_C void fx_deinit_File(void)
{
   _fx_free_R7File__t(&_fx_g12File__stdout);
}

